package com.kadron.session;

import java.util.Date;

import javax.persistence.EntityManager;
import javax.persistence.NoResultException;

import org.jboss.seam.Component;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Logger;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.contexts.Contexts;
import org.jboss.seam.international.StatusMessage.Severity;
import org.jboss.seam.log.Log;
import org.jboss.seam.security.Credentials;
import org.jboss.seam.security.Identity;

import com.kadron.common.KConst;
import com.kadron.common.KUtil;
import com.kadron.common.PasswordUtil;
import com.kadron.dao.KUserDAO;
import com.kadron.entity.User;
import com.kadron.enumeration.KLang;
import com.kadron.enumeration.UserStatus;
import com.kadron.manager.KMessageManager;
import com.kadron.service.UserHistoryService;

@Name("authenticator")
public class Authenticator extends KMessageManager {
	
    /**
	 * 
	 */
	private static final long serialVersionUID = -4420284873146226468L;

	@Logger private Log log;

    @In Identity identity;
    @In Credentials credentials;

    @In
    private KUserDAO userDAO;
    
    @In
    private UserHistoryService userHistoryService;
    
    public boolean authenticate() {
    	if (log.isInfoEnabled()) {
    		log.info("authenticating {0}", credentials.getUsername());			
		}
        //write your authentication logic here,
        //return true if the authentication was
        //successful, false otherwise
        EntityManager em = (EntityManager) Component.getInstance("entityManager");
        
        String kname = credentials.getUsername();
        String password = credentials.getPassword();
        if (KUtil.isEmpty(kname) || KUtil.isEmpty(password)) {
			return false;
		}
        String cripted = PasswordUtil.cript(password);
        User user = null;
        KUser kUser = (KUser) Component.getInstance("kUser");
		try {
			user = (User) em.createQuery("SELECT u FROM User u WHERE u.username=:username AND u.password=:password AND u.userStatus NOT IN (3,4)")
        	.setParameter("username", credentials.getUsername())
        	.setParameter("password", cripted)
        	.setMaxResults(1)
        	.getSingleResult();
			if (user != null) {
				if (UserStatus.BANNED.equals(user.getUserStatus()) || UserStatus.DELETED.equals(user.getUserStatus())) {
					String messageLOG = "NOT PERMITED USER! Username: "+credentials.getUsername() + " >>> tried to login!!";
					userHistoryService.create(user, KConst.LOGIN, KConst.LOGIN, messageLOG);
					if (log.isDebugEnabled()) {
						log.debug(messageLOG);
					}
					return false;
				}
				KLang lang = user.getLang();
				if (lang == null) {
					lang = KLang.EN;
				}
				Date moment = KUtil.getMoment();
				if (user.getUserStatus().equals(UserStatus.SIGNED_UP)) {
					user.setUserStatus(UserStatus.REGISTERED);
					user.setRegDate(moment);
					user.setStatusUpdate(moment);
					user = (User) userDAO.update(user);
					userHistoryService.create(user, KConst.REGISTRATION, KConst.REGISTRATION, "User K-NAME="+user.getUsername()+" registered as UserType="+user.getUserType()+", user ordinal="+user.getOrdinal());
					message("registration_successful", Severity.INFO);
				}
				kUser.init(user);
				userHistoryService.create(user, KConst.LOGIN, KConst.LOGIN, "Login action");
				Contexts.getSessionContext().set("klang", lang.name());
				if (user.isAdmin()) {
					identity.addRole("admin");				
				}
				return true;
			}
		} catch (NoResultException e) {
			log.info("User not found k-name:"+kname);
		}
        return false;
    }

}
